﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Stuff
{
    public class StuffFileEntry
    {
        public static string stuffPath;

        public string Path;
        public string Name;
        public int Length;
        public int Offset;
        public string FullName;
        public string Extension;
        public string StuffFullName;
        
        string stuffName;
        public string StuffName
        {
            get
            {
                if (string.IsNullOrEmpty(stuffName))
                    stuffName = System.IO.Path.GetFileName(StuffFullName);
                return stuffName;
            }
        }

        string extensionDotless;
        public string ExtensionDotless
        {
            get
            {
                if (string.IsNullOrEmpty(extensionDotless))
                    extensionDotless = Extension.TrimStart('.');
                return extensionDotless;
            }
        }


        public override string ToString()
        {
            return FullName;
        }

        public Stream GetStream()
        {
            return new StuffFileEntryStream(this);
        }

        public byte[] GetBytes()
        {
            byte[] buff = new byte[Length];
            using (Stream fs = GetStream())
                fs.Read(buff, 0, Length);
            return buff;
        }

        static byte[] intBuffer = new byte[4];
        static byte[] stringBuffer = new byte[2048];
        public static StuffFileEntry Create(Stream stream, int offset, string StuffFullName)
        {
            var ret = new StuffFileEntry();
            ret.StuffFullName = StuffFullName;
            stream.Read(intBuffer, 0, 4);
            ret.Length = intBuffer[0] + intBuffer[1] * 256 + intBuffer[2] * 65536 + intBuffer[3] * 16777216;
            ret.Offset = offset;
            stream.Read(intBuffer, 0, 4);
            int filenamelen = intBuffer[0] + intBuffer[1] * 256 + intBuffer[2] * 65536 + intBuffer[3] * 16777216 + 1;
            stream.Read(stringBuffer, 0, filenamelen);
            var fileName = System.Text.ASCIIEncoding.ASCII.GetString(stringBuffer, 0, filenamelen - 1).ToLower();
            ret.Path = System.IO.Path.GetDirectoryName(fileName);
            ret.Name = System.IO.Path.GetFileName(fileName);
            ret.Extension = System.IO.Path.GetExtension(fileName);
            if (ret.Path == string.Empty)
            {
                ret.FullName = "()\\" + fileName;
                ret.Path = "()";
            }
            else
                ret.FullName = fileName;
            return ret;
        }

        public static event EventHandler Loading;

        public static List<StuffFileEntry> LoadAll(List<FileInfo> stuffFiles)
        {
            var ret = new List<StuffFileEntry>();
            int filecount = 0;
            stuffFiles.ForEach(stuffFile =>
                {
                    
                    using (FileStream fs = stuffFile.OpenRead())
                    {
                        fs.Read(intBuffer, 0, 4);
                        filecount = intBuffer[0] + intBuffer[1] * 256 + intBuffer[2] * 65536 + intBuffer[3] * 16777216;
                        offset = 0;
                        List<StuffFileEntry> added = GetAll(filecount, fs, stuffFile.FullName).ToList();
                        long pos = fs.Position;
                        ret.AddRange(added.Select(x => { x.Offset += (int)pos; return x; }));
                        if (Loading != null)
                            Loading(null, null);
                    }
                });
            ret.Sort(new Comparison<StuffFileEntry>((s1, s2) => s1.FullName.CompareTo(s2.FullName)));
            return ret;
        }
        static int offset = 0;
        static IEnumerable<StuffFileEntry> GetAll(int filecount, Stream fs, string stuffFile)
        {
            while (filecount-- != 0)
            {
                var sfe = StuffFileEntry.Create(fs, offset, stuffFile);
                offset += sfe.Length;
                yield return sfe;
            }
        }
        
    }
}
